// # JavaBean

/*
在Java中,有很多class的定义都符合这样的规范:
	·若干private Instance field;
	·通过public方法来读写Instance field;

*/

//例如:
public class Person {
	private String name;
	private int age;

	public String getName() { return this.name; }
	public void setName() { this.name = name;}

	public int getAge() { return this.age;}
	public void setAge(int age) {this.age = age;}

}

//如果【读写方法】符合以下这种命名规范：
	//1.读方法
	public Type getXyz(){}
	//2.写方法
	public void setXyz(Type value){}


//那么这种class就被成为JavaBean：

//上面的字段是Xyz,读写的方法名分别以get和set开头,并且后接大写字母开头的field名Xyz,因此2个读写方法名分别是getXyz()和setXyz()。

//还有一种是boolean Field(字段)比较特殊,它的读方法一般命名为isXyz():
	//读方法：
	public boolean isChild() {}

	//写方法：
	public void setChild(boolean value) {}


/*
我们通常把一组对应的 
	1.读方法(getter)
	2.写方法(setter)
都成为‘属性(property)’

例如,name的property(属性):
	1.对应name的读方法：String getName()
	2.对应name的写方法：void setName(String name)

只有【getter的属性】称为‘只读属性(read-only)’
例如：定义一个age只读属性
	1.对应的age的读方法是int getAge()
	2.无对应的age的写方法是void setAge(int age)

类似的，只有‘setter的属性’称为‘只写属性(write-only)’

很明显，只读属性很常见，只写属性不常见。

属性只要定义getter和setter方法,不一定需要对应的field字段.
例如：child只读属性定义如下： */
public class Person {
	private String name;
	private int age;

	//name
	public String getName() {return this.name;}
	public void setName(String name) {this.name = name;}

	//age
	public int getAge() {return this.age;}
	public void setAge(int age) { this.age = age;}

	//boolean
	public boolean isChild() { return age<=6;}
}

//可以看出,getter和setter也是【一种数据封装的方法】。




//# JavaBean的作用
/* 
JavaBean主要用来传递数据,即把一组数据组合成一个JavaBean,这样可以便于传输数据.此外,JavaBean可以方便地被IDE工具分析,生成读写属性的代码,主要用在图形界面的可视化设计中.

通过IDE,可以快速生成getter和setter.

例如,在Eclipse中,先输入以下代码: */
public class Person {
	private String name;
	private int age;
}
//然后,点击‘右键’,在弹出的菜单中选择"Source","Generate Getters and Setters",在弹出的对话框中选中,选中你需要生成的的getter和setter的Method的field,点击确定即可让IDE自动完成所有你要操作的Field的Method的代码.



// # 枚举JavaBean属性
//要enum一个JavaBean的所有属性,可以直接使用Java核心库提供的Introspector：
import java.beans.*;

public class Main {
	public static void main(String[] args) throws Exception {
		BeanInfo info = Introspector.getBeanInfo(Person.class);

		for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
			System.out.println(pd.getName());

			System.out.println(" " + pd.getReadMethod());
			System.out.println(" " + pd.getWriteMethod());
		}
	}
}

class Person {
	private String name;
	private int age;

	//name
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}

	//age
	public void getAge() {return age;}
	public void setAge() {this.age = age;}
}

//运行上述代码,可以列出所有的属性,以及对应的‘读写方法’。注意:class属性是从Object继承的getClass方法所带来的。




/* # 小结
1.【JavaBean】是【一种命名规范的class】,它通过getter和setter来定义【属性】;

2.【属性(property)】是'一种通用的叫法',并非Java语法规定;
(ps:我们通常把一个class中对field的操作: 1.读方法(getter)和2.写方法(setter) 称为 '属性(property)'.也就是说,属性(property)是根据一个class里面的变量(field)来进行划分子项)

3.可以利用IDE快速生成getter和setter
(选中class->右键->Source->Generate Getters and Setters)

4.使用【Introspector.getBeanInfo】可以获取'属性列表(property list)'


5.BeanInfo就是'属性列表'; 通过Introspector(提醒器).getBeanInfo(字节码文件)获取

6. 一个class文件,对应一个BeanInfo; 一个BeanInfo(属性列表),对应n个'PropertyDescriptor(属性描述器)'

7. PropertyDescriptor是1个属性描述器,里面具有
	1.Name
	2.ReadMethod
	3.WriteMethod
*/



// JavaBean核心操作代码
BeanInfo info = Introspector.getBeanInfo(Person.class);

for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
	System.out.print(pd.getName());
	System.out.print(" " + pd.getReadMethod());
	System.out.print(" " + pd.getWriteMethod());
}







